package cn.hl.hm.util;

import java.io.BufferedOutputStream;
import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.net.HttpURLConnection;
import java.net.Inet4Address;
import java.net.InetAddress;
import java.net.NetworkInterface;
import java.net.URL;
import java.util.Enumeration;
import java.util.Formatter;
import java.util.Iterator;
import java.util.Map;
import java.util.Random;
import java.util.Set;
import java.util.SortedMap;
import java.util.TreeMap;

import javax.servlet.http.HttpServletRequest;

import org.apache.commons.lang.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import com.alibaba.fastjson.JSONObject;
import com.thoughtworks.xstream.XStream;
import com.thoughtworks.xstream.io.xml.XmlFriendlyNameCoder;
import com.thoughtworks.xstream.io.xml.XppDriver;

import cn.hl.hm.entity.UnifiedOrderRequest;
import cn.hl.hm.entity.UnifiedOrderRespose;

public class WXUtil {
	 private static final Logger logger = LoggerFactory
	            .getLogger(WXUtil.class);
	private static final String getTokenUrl = "https://api.weixin.qq.com/cgi-bin/token?grant_type=client_credential&appid=APPID&secret=APPSECRET";
	private static final String sendUrl = "https://api.weixin.qq.com/cgi-bin/message/template/send?access_token=ACCESS_TOKEN";
	//jsapi_ticket
	private static final String getJsapi_ticket="http://api.weixin.qq.com/cgi-bin/ticket/getticket?type=jsapi&access_token=ACCESS_TOKEN"; 
	//统一下单
	private static final String getTYX_URL="https://api.mch.weixin.qq.com/pay/unifiedorder"; 

	 private static String localIp;
	
	public static String getNonceStr() {
		Random random = new Random();
		return MD5Util.MD5Encode(String.valueOf(random.nextInt(10000)), "GBK");
	}

	public static String getTimeStamp() {
		return String.valueOf(System.currentTimeMillis() / 1000);
	}
	/** 统一订单生成签名
	 * 生成签名 
	 *  
	 * @param appid_value 
	 * @param mch_id_value 
	 * @param productId 
	 * @param nonce_str_value 
	 * @param trade_type  
	 * @param notify_url  
	 * @param spbill_create_ip  
	 * @param total_fee  
	 * @param out_trade_no  
	 * @return 
	 */  
	public static String createSign(UnifiedOrderRequest unifiedOrderRequest) {  
	    //根据规则创建可排序的map集合  
	    SortedMap<String, Object> packageParams = new TreeMap<String, Object>();  
	    packageParams.put("appid", unifiedOrderRequest.getAppid());  
	    packageParams.put("body", unifiedOrderRequest.getBody());  
	    packageParams.put("mch_id", unifiedOrderRequest.getMch_id());  
	    packageParams.put("nonce_str", unifiedOrderRequest.getNonce_str());  
	    packageParams.put("notify_url", unifiedOrderRequest.getNotify_url());  
	    packageParams.put("out_trade_no", unifiedOrderRequest.getOut_trade_no());  
	    packageParams.put("spbill_create_ip", unifiedOrderRequest.getSpbill_create_ip());  
	    packageParams.put("trade_type", unifiedOrderRequest.getTrade_type());  
	    packageParams.put("total_fee", unifiedOrderRequest.getTotal_fee());  
	    //packageParams.put("openid", "oZY8awwVRlhPlL4AqG7SofTlPGK4");  
	    StringBuffer sb = new StringBuffer();  
	    Set es = packageParams.entrySet();//字典序  
	    Iterator it = es.iterator();  
	    while (it.hasNext()) {  
	        Map.Entry entry = (Map.Entry) it.next();  
	        String k = (String) entry.getKey();  
	        String v = (String) entry.getValue();  
	        //为空不参与签名、参数名区分大小写  
	        if (null != v && !"".equals(v) && !"sign".equals(k)  
	                && !"key".equals(k)) {  
	            sb.append(k + "=" + v + "&");  
	        }  
	    }  
	    //第二步拼接key，key设置路径：微信商户平台(pay.weixin.qq.com)-->账户设置-->API安全-->密钥设置  
	    sb.append("key=" +unifiedOrderRequest.getKey());  
	    System.out.println(sb.toString());
	   /* String sign = MD5Util.md5(sb.toString())  
	            .toUpperCase();*///MD5加密  
	 //String sign=MD5.signOne(sb.toString(),"UTF-8").toUpperCase();;
	   String sign = MD5Util.MD5Encode(sb.toString(),"UTF-8");
	    sign=sign.toUpperCase();
	    ///////////
	   /* String sign=null;
	    try{
	    
	    MessageDigest crypt = MessageDigest.getInstance("SHA-1");
        crypt.reset();
        crypt.update(sb.toString().getBytes("UTF-8"));
         sign =byteToHex(crypt.digest()).toUpperCase();
	    }catch(Exception e){
	    	e.printStackTrace();
	    }*/
	    /////////
	    /*String sign=null;
	    try{
	    MessageDigest md5 = MessageDigest.getInstance("MD5");
	         md5.reset();
	          md5.update(sb.toString().getBytes("UTF-8"));
	          sign =byteToStr(md5.digest()).toUpperCase();
	    }catch(Exception e){
	    	e.printStackTrace();
	    }*/
	    return sign;  
	}  
	/**
	 * 获取本机的网络IP
	 */
	public static String getLocalNetWorkIp() {
	    if (localIp != null) {
	        return localIp;
	    }
	    try {
	        Enumeration<NetworkInterface> netInterfaces = NetworkInterface.getNetworkInterfaces();
	        InetAddress ip = null;
	        while (netInterfaces.hasMoreElements()) {// 遍历所有的网卡
	            NetworkInterface ni = (NetworkInterface) netInterfaces.nextElement();
	            if (ni.isLoopback() || ni.isVirtual()) {// 如果是回环和虚拟网络地址的话继续
	                continue;
	            }
	            Enumeration<InetAddress> addresss = ni.getInetAddresses();
	            while (addresss.hasMoreElements()) {
	                InetAddress address = addresss.nextElement();
	                if (address instanceof Inet4Address) {// 这里暂时只获取ipv4地址
	                    ip = address;
	                    break;
	                }
	            }
	            if (ip != null) {
	                break;
	            }
	        }
	        if (ip != null) {
	            localIp = ip.getHostAddress();
	        } else {
	            localIp = "127.0.0.1";
	        }
	    } catch (Exception e) {
	        localIp = "127.0.0.1";
	    }
	    return localIp;
	}

/** 
 * 调统一下单API 
 * @param orderInfo 
 * @return 
 */  
public static String httpOrder(String orderInfo) {  
    String url =getTYX_URL;  
    try {  
        HttpURLConnection conn = (HttpURLConnection) new URL(url).openConnection();  
        //加入数据    
           conn.setRequestMethod("POST");    
           conn.setDoOutput(true); 
           conn.setRequestProperty("contentType", "UTF8");  
           BufferedOutputStream buffOutStr = new BufferedOutputStream(conn.getOutputStream());    
           buffOutStr.write(orderInfo.getBytes("UTF-8"));  
           buffOutStr.flush();    
           buffOutStr.close();    
               
           //获取输入流    
           BufferedReader reader = new BufferedReader(new InputStreamReader(conn.getInputStream(),"UTF-8"));    
               
           String line = null;    
           StringBuffer sb = new StringBuffer();    
           while((line = reader.readLine())!= null){    
               sb.append(line);    
           }    
             
           XStream xStream = new XStream(new XppDriver(new XmlFriendlyNameCoder("_-", "_")));//说明3(见文末)  
           //将请求返回的内容通过xStream转换为UnifiedOrderRespose对象  
           xStream.alias("xml", UnifiedOrderRespose.class);  
           UnifiedOrderRespose unifiedOrderRespose = (UnifiedOrderRespose) xStream.fromXML(sb.toString());  
             
           //根据微信文档return_code 和result_code都为SUCCESS的时候才会返回code_url  
           //<span style="color:#ff0000;"><strong>说明4(见文末)</strong></span>  
           if(unifiedOrderRespose!=null){
        	   logger.info("...预支付返回："+unifiedOrderRespose.getReturn_code()+" "+unifiedOrderRespose.getResult_code()+" "+unifiedOrderRespose.getReturn_msg());
           }
           if(null!=unifiedOrderRespose   
                && "SUCCESS".equals(unifiedOrderRespose.getReturn_code())   
                && "SUCCESS".equals(unifiedOrderRespose.getResult_code())){  
            return unifiedOrderRespose.getPrepay_id();  
           }else{  
            return null;  
           }  
    } catch (Exception e) {  
        e.printStackTrace();  
    }  
    return null;  
}  

public static  String getAccessToken(String  accessToken1) {
	String accessToken = "";
	if (StringUtils.isNotEmpty(accessToken)){
		return accessToken;
	}
	String jsapi_ticket=null;
	String url = getJsapi_ticket.replace("access_token",accessToken);
								
	// 取得结果
	String json=HttpUtil.httpsRequest(url, "GET", null);
	// 取得json对象
	JSONObject jsonObject=JSONObject.parseObject(json);
	try{
		// 取得jsapi_ticket
		jsapi_ticket=jsonObject.getString("ticket");
		
		// 取得失效时间
		//String expiresIn=jsonObject.getString("expires_in");
		// 日志打印
		//logger.info("开始放入缓存！"+wechatMpOffical.getTokenKey()+"令牌环失效时间："+expiresIn);
		// 放入缓存！
		////CacheUtils.set(wechatMpOffical.getTokenKey(), accessToken, Integer.parseInt(expiresIn)); // 缓存时间为返回的时间
		// 日志打印
		//logger.info(wechatMpOffical.getTokenKey()+"放入缓存成功:"+accessToken+"令牌环失效时间："+expiresIn);
		return accessToken;
	} catch (Exception e){
		logger.info("获取access_token失败："+e.getMessage());
	
		return "";
	}
}
//第二支付时候签名
public static String createSignTwo(UnifiedOrderRequest unifiedOrderRequest) {
    //根据规则创建可排序的map集合  
    SortedMap<String, String> packageParams = new TreeMap<String, String>();  
    packageParams.put("appid", unifiedOrderRequest.getAppid());  
    packageParams.put("noncestr", unifiedOrderRequest.getNonce_str());
    packageParams.put("package", "Sign=WXPay"); 
    packageParams.put("partnerid", unifiedOrderRequest.getMch_id());  
    packageParams.put("prepayid", unifiedOrderRequest.getPrepay_id());  
    packageParams.put("timestamp", unifiedOrderRequest.getTimestamp());  
   
    StringBuffer sb = new StringBuffer();  
    Set es = packageParams.entrySet();//字典序  
    Iterator it = es.iterator();  
    while (it.hasNext()) {  
        Map.Entry entry = (Map.Entry) it.next();  
        String k = (String) entry.getKey();  
        String v = (String) entry.getValue();  
        //为空不参与签名、参数名区分大小写  
        if (null != v && !"".equals(v) && !"sign".equals(k) 
                && !"key".equals(k)) {  
            sb.append(k + "=" + v + "&");  
        }  
    }  
    //第二步拼接key，key设置路径：微信商户平台(pay.weixin.qq.com)-->账户设置-->API安全-->密钥设置  
    sb.append("key=" +unifiedOrderRequest.getKey());  
   /* String sign = MD5Util.md5(sb.toString())  
            .toUpperCase();*///MD5加密  
  // String sign=MD5.signOne(sb.toString(),"utf-8").toUpperCase();;
    System.out.println(sb.toString());
    String sign = MD5Util.MD5Encode(sb.toString(), "UTF-8");
    sign=sign.toUpperCase();
   // String sign= byteToStr(sb.toString().getBytes()).toUpperCase();
    
    return sign;  
}  
public static String byteToStr(byte[] byteArray) {
    String strDigest = "";
   for (int i = 0; i < byteArray.length; i++) {
       strDigest += byteToHexStr(byteArray[i]);
    }
    return strDigest;
}
public static String byteToHexStr(byte bytes) {
   char[] Digit = { '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'A', 'B', 'C', 'D', 'E', 'F' };
    char[] tempArr = new char[2];
   tempArr[0] = Digit[(bytes >>> 4) & 0X0F];
    tempArr[1] = Digit[bytes & 0X0F];

    String s = new String(tempArr);
    return s;
}
public static String getIpAddr(HttpServletRequest request) {  
    InetAddress addr = null;  
    try {  
        addr = InetAddress.getLocalHost();  
    } catch (Exception e) {  
        return request.getRemoteAddr();  
    }  
    byte[] ipAddr = addr.getAddress();  
   String ipAddrStr = "";  
    for (int i = 0; i < ipAddr.length; i++) {  
        if (i > 0) {  
           ipAddrStr += ".";  
       }  
       ipAddrStr += ipAddr[i] & 0xFF;  
   }  
    return ipAddrStr;  
}  
private static String byteToHex(final byte[] hash) {
    Formatter formatter = new Formatter();
    for (byte b : hash)
    {
        formatter.format("%02x", b);
    }
    String result = formatter.toString();
    formatter.close();
    return result;
}
}
